<?php


namespace app\common\service\lib\Pay;


use app\admin\model\Config;
use app\admin\model\order\Order;
use app\admin\model\order\OrderGoodsInfo;
use app\admin\model\store\Goods;
use app\admin\model\store\GoodsSku;
use app\admin\model\user\Bill;
use app\common\service\BaseService;
use app\common\service\lib\DelayQueue;
use app\common\service\user\BillService;
use think\facade\Db;
use think\facade\Log;
use think\Request;
use Yansongda\Pay\Pay;

class AliPayFactory extends BaseService implements PayFactoryInterface
{

    protected static $config = [ 'app_id' => '2021000117606333',
        'notify_url' => 'http://sx1.51chow.com/api/pay/notify',
        'return_url' => 'http://www.sx.com:7888/api/pay/return',
        'ali_public_key' =>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtQjZhJvM+FfbtaUKkZkZo+rtTtNcCuZNqEVs1wdxaymv0o+UbNWo0HnzkzEiczLkFBQ/hK1045cRgFV+lNHS4wAz07R/XNOM8wyOuBf1ViqKB/947cSFnZJAk8vi5EbehzK5fygPeGpwzfINu7y4UlQBNTmN2jtB3XS69niiDoCj3DbfeJaiY9rdi85BwRWk75hv19zAlGtVOLVrMg0L0KNP2O6D260vx/Vv2uEkOsXO5wjOTxnsAkyKkpSDPW17xASXsJNkkxZ/gkkChvl6AcIuBN5kuO4BWTR3kziTEG/U1srMM10E4UeYCgnQvP55/8CvbJi0tzh3uO35h2ArYwIDAQAB',
        'private_key' => 'MIIEowIBAAKCAQEAmTirBxPNzxqI8nvBgZL0dKo2o1Ha2XZb/YvwEcRmpstvqHb1izZpxuHSe6mbICpJv4KfOdAxFH1pvlVVc55lDm6GV/RqK5CzJeNOHb4wrMDswhUZW8PPQh0X/+xnzFgUEv38O9k8kqxmKgZyjj0nRAJziTHVRkHRbPLO//wuycgmqeClmJjNOjz1QLbfTZZ6dUYLqMlIxKfSKinBiLO5F+jvBI9lAPbnu2cIx/qHSkVEae3FNaGuUiOG81XRNFohtTR0HD6dZXwvIGQvsOynDj1WeFeE96q2gx60q0JnYaVMYLir7Kdw53E3cmdFrb3UqsYwSphDFPLT4pQ1BIzGNQIDAQABAoIBAGcs7KX4ZPdX8+3s/fHl5i0FTYOOpCMZe3pxl/gu27zncsnrSQ80Vegxuo3BOQ9gyoZmTBgfJF2a0fDz/3W6rGwaauahVDj/2FLkDH8kyhwaUZOjp47OfSsU8ktIguDsUqAzXX1jnFFcO/OCofM8JMu8Jta0stv7iC2oF1HzHAKNb0S5DeZJnJ9CeSlL57TL3SNOPXmNwIQhi7QN4FRJjm3g0uU5lDa7uBYwM5ynkcavn+NAfN0ERexny7JyV2g8boQLmKjk6Xrz5k2ndnRjK6/Gc/6dO8jh7ZSQQu6pFY4LstoEqnKb8ITgzQ36Oqx1wB+vlLBo6MkCiLi73EjZOyECgYEA9AD+B0ggxz+B53YZyMXYp6WE2JqnIETX4QxQafixbcH6x8VKI4bVWiXgSFgG1ZVo7+5v1LUfF1b6zHSeQ7TTtLGdnLJRutWEr8kAHENtx40GJRjFQVh0ZzRXrObYuAy/mLy2yJvkfixvleAfvFsAMZPW5/GbAKPK665QAn7krs0CgYEAoMEYqu3ojMmbpq59jGaTCsoSyl+HzqHaBlmqJMNUjYb/rGIx76o+hJ9Jomyaj4gmlYpSnJ4uVPZ5PR5Vq0PbnRhSLv+2kCfJONnuIBYPhi7BPQzX3fFgvx+MIAD/WN5I2fsDIefchJEDACOenyjeCZ4/mwui8C+BT+87cBg7JQkCgYEAn3CmjYuMH6ZX9C8v2gmt8J4vmHo2CtfxWJT7VsOy7M18WV2JfH12nFlznNIoZRgkYeOkH5Hapx2m9EKfyA446DHHk8TRswwij9r/v3gwG90CzurIulJafbWuNMUDiACMkfl+VsfHHstafszc7+9myP6ZxyYQ6vIcfrSAg6D3PWECgYB/lEArh9zDv01Un67sOowASBdZnS9/AlyyJX8u5ga4u6c1/Eh9WLN9NZ2O1npj5z4X+EtQGQnUTDg0FVsQLS6iIqc2vaL6DVlZUTv3Iwr3Byw9c2/uqJ6LkFH5JFGDCgbvWJNH2Wfdneivt5Uv45M0Nu9r8XRDArCx679UWya1YQKBgC5VZGXC5nWhf0op7VURx20+x+kT3yhQiTfhLdTbbaUxlEtvRIuewlN3rhT3nBD4KgJ5hfbDIyPupjBXakM0u4D/pIYcpp9grMPDLB972kB1MqwWSV9khLJ/fF2lu8h4aRHigwoYc3rP0Oj81L+6GEjxHMOEkg0rRquRNZJ13NGv',
        'log' => [ // optional
            'file' => './logs/alipay.log',
            'level' => 'info', // 建议生产环境等级调整为 info，开发环境为 debug
            'type' => 'single', // optional, 可选 daily.
            'max_file' => 30, // optional, 当 type 为 daily 时有效，默认 30 天
        ],
        'http' => [ // optional
            'timeout' => 5.0,
            'connect_timeout' => 5.0,
            // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
        ],
        'mode' => 'dev', // optional,设置此参数，将进入沙箱模式]
    ];


    /**
     * Author:YangXinPeng
     * 支付宝支付
     * @param $params
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public static function createMode($params)
    {
        $order = [
            'out_trade_no' => $params['order_id'],
            'total_amount' => $params['pay_price'],
            'subject' => "订单 " . $params['order_id'],
        ];
        $alipay = Pay::alipay(self::$config)->web($order);
        return $alipay->send();
    }

    /**
     * Author:YangXinPeng
     * 支付宝退款
     * @param $params
     * @return array
     * @throws \Yansongda\Pay\Exceptions\GatewayException
     * @throws \Yansongda\Pay\Exceptions\InvalidConfigException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     */
    public static function refund($params)
    {
        $order = [
            'out_trade_no' => $params['order_id'],
            'refund_amount' => $params['pay_price'],
        ];
       $res =  Pay::alipay(self::$config)->refund($order);
       $result = json_decode($res,true);
       if ($result['msg'] == 'Success'){
           return self::success('退款成功');
       }else{
           return self::success('退款失败');
       }
    }

    /**
     * Author:YangXinPeng
     * 支付宝异步回调
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function notify()
    {
        // 支付宝验签
        $data = Pay::alipay(self::$config)->verify();
        $tradeStatus = $data->trade_status;
        $tradeNo = $data->out_trade_no;
        $totalAmount = $data->total_amount;
        //  TRADE_SUCCESS 或 TRADE_FINISHED 时，支付宝才会认定为买家付款成功。
        if ($tradeStatus == 'TRADE_SUCCESS'){
            //商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号；
            $order = Order::where('order_no', $tradeNo)->find();
            if ($order) {
                $order = $order->toArray();
                //判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额）；
                if ($order['pay_price'] !=$totalAmount) {
                    Log::info('订单支付金额有误!');
                    return 'fail';
                }
                $pm= 0;
                $type = "alipay";
                $title = "支付宝支付";
                //修改订单状态
                Db::startTrans();
                try {
                    if ($order['pink_id'] != 0){
                        $count = Order::where('pink_no',$order['pink_no'])->count();
                        $pinkPeople = Order::where('pink_id',$order['pink_id'])->value('pink_people');
                        if ($pinkPeople == $count){
                            Order::where('pink_no',$order['pink_no'])
                                ->update(['is_pink_status'=>1]);
                        }
                    }
                    Order::where('order_no', $tradeNo)
                        ->update([ 'pay_status' => 1,'status'=>1,'pay_time' => time(), 'pay_type' => 2]);
                    BillService::createBill($order,$pm,$type,$title);

                    // 提交事务
                    Db::commit();
                } catch (\Exception $e) {
                    file_put_contents('alipay.log',var_export($e->getMessage(),true),FILE_APPEND);
                    // 回滚事务
                    Db::rollback();
                    return 'fail';
                }
            } else {
                Log::info('订单编号有误');
                return 'fail';
            }
        }
        return 'success';
    }


    /**
     * Author:YangXinPeng
     * 支付宝同步回调
     * @return string
     * @throws \Yansongda\Pay\Exceptions\InvalidConfigException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     */
    public static function returnUrl()
    {
        $data = Pay::alipay(self::$config)->verify();
        $tradeNo = $data->out_trade_no;
        $totalAmount = $data->total_amount;
        header("Location: http://192.168.43.93:8080/#/pages/PayResult/PayResult?order_no=$tradeNo&totalPrice=$totalAmount");
    }

    /**
     * Author:YangXinPeng
     * 支付宝订单超时处理 生成者
     * @param $orderId
     */
    public static function quePay($orderId)
    {
        $delay = new DelayQueue();
        $ttl = 1000 * 60 * 30;//订单30m后超时
        $delayExName = 'delay-pay-exchange';//超时exchange
        $delayQueueName = 'delay-pay-queue';//超时queue
        $queueName = 'ttl-pay-queue';//订单queue
        $delay->createQueue($ttl, $delayExName, $delayQueueName, $queueName);
        $data = [
            'order_id' => $orderId,
        ];
        $delay->sendMessage(json_encode($data), $queueName);
        sleep(1);
    }


    /**
     * Author:YangXinPeng
     * 支付宝订单超时处理 消费者
     * @throws \ErrorException
     */
    public static function consumeOrder()
    {
        $delay = new DelayQueue();
        $delayQueueName = 'delay-pay-queue';
        $callback = function ($msg) {
            $val = json_decode($msg->body, true);
            $orderId = $val['order_id'];
            $skuIds = [];
            $arr = OrderGoodsInfo::where('oid', $orderId)->select();
            $arr && $arr = $arr->toArray();
            foreach ($arr as $key=>$v){
                $skuIds [$key]['sku_id'] = $v['goods_sku_id'];
                $skuIds [$key]['num'] = $v['sku_num'];
            }
            Db::startTrans();
            try {
                Order::where('order_id', $orderId)
                    ->update([ 'status' => 4 ]);
                foreach ($arr as $value){
                    $goodId = GoodsSku::where('id',$value['sku_id'])->value('goods_id');
                    GoodsSku::where('id',$value['sku_id'])->inc('sku_tock', $v['num'])->update();
                    Goods::where('id', $goodId)->inc('goods_stock', $v['num'])->update();
                }
                // 提交事务
                Db::commit();
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
            }
            $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
            sleep(1);
        };
        /**
         * 消费已经超时的订单信息，进行处理
         */
        $delay->consumeMessage($delayQueueName, $callback);
    }

    /**
     * Author:YangXinPeng
     * 查询支付订单
     * @param $order_id
     * @throws \Yansongda\Pay\Exceptions\GatewayException
     * @throws \Yansongda\Pay\Exceptions\InvalidConfigException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     */
    public static function find($order_id)
    {
        $order = [
            'out_trade_no' => $order_id,
        ];
        $alipay = Pay::alipay(self::$config);
        $result = $alipay->find($order);
        return $result;
    }


}